﻿using System;
using System.Reflection;

namespace Useful.MVP2
{
    public abstract class BaseListPresenter<M, IV, IR> : BasePresenter<M, IV, IR>
        where M : BaseListModel, new()
        where IV : IListView
    {
        protected BaseListPresenter(IV view, IR repository, IPresenterImpl presenterImpl)
            : base(view, repository, presenterImpl)
        {
            View.RefreshClicked += View_RefreshClicked;
            View.AddClicked += View_AddClicked;
            View.EditClicked += View_EditClicked;
            View.DeleteClicked += View_DeleteClicked;
            View.CurrentItemPositionChanged += View_CurrentItemPositionChanged;
            View.ViewInited += View_ViewInited;
        }

        private void View_ViewInited(object sender, InitListViewEventArgs e)
        {
            try
            {
                OnViewInited(e);
            }
            catch (Exception ex)
            {
                HandleException(MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        private void View_CurrentItemPositionChanged(object sender, EventArgs e)
        {
            try
            {
                object item = View.GetCurrentItem();

                View.EnableEdit = item != null && Model.AllowEdit;
                View.EnableDelete = item != null && Model.AllowDelete;

                OnCurrentItemPositionChanged(item);
            }
            catch (Exception ex)
            {
                HandleException(MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        private void View_DeleteClicked(object sender, EventArgs e)
        {
            try
            {
                object item = View.GetCurrentItem();

                if (item != null && Model.AllowDelete)
                {
                    if (ShowQuestion("Вы действительно ходите удалить элемент?"))
                    {
                        OnDeleteClicked(item);

                        ShowWarring("OK");
                    }
                }
            }
            catch (Exception ex)
            {
                HandleException(MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        private void View_EditClicked(object sender, EventArgs e)
        {
            try
            {
                object item = View.GetCurrentItem();

                if (item != null && Model.AllowEdit)
                {
                    OnEditClicked(item);
                }
            }
            catch (Exception ex)
            {
                HandleException(MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        private void View_AddClicked(object sender, EventArgs e)
        {
            try
            {
                if (Model.AllowAdd)
                {
                    OnAddClicked();
                }
            }
            catch (Exception ex)
            {
                HandleException(MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        private void View_RefreshClicked(object sender, EventArgs e)
        {
            try
            {
                GetFilterFromView();

                if (ValidateFilters() && Model.AllowView)
                {
                    OnRefreshClicked();
                }
            }
            catch (Exception ex)
            {
                HandleException(MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        protected abstract void OnRefreshClicked();
        protected abstract void OnAddClicked();
        protected abstract void OnEditClicked(object item);
        protected abstract void OnDeleteClicked(object item);
        protected abstract void OnCurrentItemPositionChanged(object item);

        protected abstract bool ValidateFilters();
        protected abstract void GetFilterFromView();

        protected override void OnViewLoad()
        {
            View.EnableView = Model.AllowView;
            View.EnableAdd = Model.AllowAdd;

            View.EnableEdit = false;
            View.EnableDelete = false;
        }

        protected override void OnViewClose()
        {
            Model.Dispose();
        }

        protected virtual void OnViewInited(InitListViewEventArgs e)
        {
            Repository = (IR)e.Repository;
            Model.AllowView = e.AllowView;
            Model.AllowAdd = e.AllowAdd;
            Model.AllowEdit = e.AllowEdit;
            Model.AllowDelete = e.AllowDelete;
        }
    }
}
